package com.dap.core.config;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyResourceConfigurer;


public class ComponentPropertyConfigLoader extends PropertyResourceConfigurer {
	protected final Logger logger = LoggerFactory.getLogger(ComponentPropertyConfigLoader.class);
    public static final String DEFAULT_PREFIX_SEPARATOR = ".";
    private String configBeanId;
    private String propPrefix;
    private final String prefixSeparator = ".";


    public String getConfigBeanId() {
        return this.configBeanId;
    }


    public void setConfigBeanId(String configBeanId) {
        this.configBeanId = configBeanId;
    }


    public String getPropPrefix() {
        return this.propPrefix;
    }


    public void setPropPrefix(String propPrefix) {
        this.propPrefix = propPrefix;
    }


    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        try {
            Properties ex = mergeProperties();
            convertProperties(ex);
            processProperties(beanFactory, ex);
        } catch (IOException ioe) {
            throw new BeanInitializationException("Could not load properties", ioe);
        }
    }


    @Override
    protected void processProperties(ConfigurableListableBeanFactory factory, Properties props) throws BeansException {
        for (Enumeration<?> names = props.propertyNames(); names.hasMoreElements();) {
            String key = (String) names.nextElement();
            try {
                int separatorIndex = key.indexOf(this.prefixSeparator);
                if (separatorIndex > 0) {
                    String prefix = key.substring(0, separatorIndex);
                    if (prefix.equals(this.propPrefix)) {
                        String beanProperty = key.substring(separatorIndex + 1);
                        applyPropertyValue(factory, this.configBeanId, beanProperty, props.getProperty(key));
                        if (this.logger.isDebugEnabled()) {
                            this.logger.debug("Property '" + key + "' set to value [" + props.getProperty(key) + "]");
                        }
                    }
                }
            } catch (BeansException ex) {
                String msg = "Could not process key '" + key + "' in ComponentPropertyConfigLoander";
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug(msg, ex);
                }
            }
        }
    }


    protected void applyPropertyValue(ConfigurableListableBeanFactory factory, String beanName, String property, String value) {
        BeanDefinition bd = factory.getBeanDefinition(beanName);
        while (bd.getOriginatingBeanDefinition() != null) {
            bd = bd.getOriginatingBeanDefinition();
        }
        PropertyValue pv = new PropertyValue(property, value);

        pv.setOptional(false);
        bd.getPropertyValues().addPropertyValue(pv);
    }
}
